//#include <connection.hpp>
#include <http/http_connection.hpp>


HTTPConnection::HTTPConnection()
{
  sock = 0;
  bytes = 0;
  memset(&server_addr_ipv4, 0, sizeof(sockaddr_in));
  memset(&server_addr_ipv6, 0, sizeof(sockaddr_in6));
};

HTTPConnection::~HTTPConnection()
{
  sock = 0;
  bytes = 0;
  memset(&server_addr_ipv4, 0, sizeof(sockaddr_in));
  memset(&server_addr_ipv6, 0, sizeof(sockaddr_in6));
};


/*
 * create_http_connection:
 *
 * Connects to the specified port of the remote HTTP server and
 * returns the sock fd.
 *
 * addr: The IP address to connect to, in dotted decimal format.
 * port: The remote port, 80 by default.
 *
 */
int HTTPConnection::create_http_connection(char* ip_addr, int port = 80, int ip_ver = 4)
{
  char* ip_address = (char*) ip_addr;
  ip = string(ip_addr);
  int resp = 0;
  int sock_type = SOCK_STREAM;
  int sock_family = AF_INET;
  int proto = 0;/* 0 - TCP;1-UCP;others - TCP*/

  if(proto == 0) {
    sock_type = SOCK_STREAM;
  } else {
    sock_type = SOCK_DGRAM;
  }

  if(ip_ver == 4) {
    sock_family = AF_INET;
  } else if(ip_ver == 6) {
    sock_family = AF_INET6;
  }

  sock = socket(sock_family, sock_type, 0);
  if(sock < 0) {
    //Raise Exception.
  }
  if(ip_ver == 4) {
    server_addr_ipv4.sin_family = AF_INET;
    server_addr_ipv4.sin_port = htons(port);
    inet_pton(AF_INET, ip_address, &server_addr_ipv4.sin_addr);
    resp = connect( sock,
		    (struct sockaddr*) &server_addr_ipv4,
		    sizeof(server_addr_ipv4));
  } else if(ip_ver == 6) {
    server_addr_ipv6.sin6_family = AF_INET6;
    server_addr_ipv6.sin6_port = htons(port);
    inet_pton(AF_INET, ip_address, &server_addr_ipv6.sin6_addr);
    resp = connect( sock,
		    (struct sockaddr*) &server_addr_ipv6,
		    sizeof(server_addr_ipv6));
  }

  if(resp < 0) {
    //Raise Exception.
    return -1;
  }
  return sock;
}

void HTTPConnection::send_request(HTTPRequest req)
{
  string request = "";

  int req_type;
  string server_uri;
  string document_uri;
  string headers;
  string data;
  string version;

  req.set_server(ip);
  req_type = req.get_request_type();
  if(req_type == GET) {
    request += "GET ";
  } else if(req_type == POST) {
    request += "POST ";
  }

  server_uri = req.get_server();
  if(server_uri.find("http://") == string::npos) {
    server_uri = "http://" + server_uri;
  }

  document_uri = req.get_uri_path();

  version = req.get_version();

  headers = req.get_headers();
  
  data = req.get_data();

  request += server_uri + document_uri + " " + version + "\r\n";
  request += headers + "\r\n";
  request += "\r\n" + data + "\r\n";
  
  write(sock, request.c_str(), request.length());
}

// HTTPResponse HTTPConnection::get_response(int timeout = 0)
// {
//   string response;
//   string buffer(512,0);
//   HTTPResponse rsp;
//   while(1) {
//     read(sock,buffer.c_str(),512);
//     if(buffer.find("\r\n") == 0 || buffer.find("\r\n") == 1 ) {
//       break;
//     }
//     response += buffer;
//     buffer.clear();
//     buffer.reserve(512);
//   }
//   rsp.build_response(response);
//   return rsp;
// }

string  HTTPConnection::get_response(int timeout = 0)
{
  string response_data = "";
  string buffer;
  HTTPResponse rsp;
  buffer.reserve(512);
  //  while(1) {
    read(sock,(char*)buffer.c_str(),512);
    if(buffer.find("\r\n") == 0 || buffer.find("\r\n") == 1 ) {
      //      break;
    }
    response_data += buffer;
    buffer.clear();
    buffer.reserve(512);
    //}
    //return response_data;
    return buffer;
}
